package org.omich.loaves.gui;

import java.util.Map;
import java.util.Set;

import org.omich.loaves.IBrainClient;
import org.omich.loaves.IGettingsStatusHandler;
import org.omich.loaves.LoavesStatus;
import org.omich.loaves.R;
import org.omich.loaves.LoavesStatus.EatingLoaf;
import org.omich.loaves.gui.view.LoavesList;
import org.omich.loaves.gui.view.Person;

import android.app.Activity;
import android.app.AlertDialog;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

public class GameController
{
	private Person mPlayerView1;
	private Person mPlayerView2;
	private LoavesList mLoavesList;
	private LoafClickListener mLoafClickListener = new LoafClickListener();

	private IBrainClient mClient;
	private Activity mActivity;
	
	private LoavesStatus mLoavesStatus;
	private String mPlayerName;
	private boolean mIsFinish = false;

	public GameController (Activity activity)
	{
		ListView l = (ListView) activity.findViewById(R.id.loavesList);
		l.setOnItemClickListener(mLoafClickListener);
		mLoavesList = new LoavesList(l);
		
		mPlayerView1 = (Person) activity.findViewById(R.id.player1);
		mPlayerView2 = (Person) activity.findViewById(R.id.player2);

		mActivity = activity;
	}
	
	public void setClient (IBrainClient client)
	{
		mClient = client;
	}
	
	public void startGame ()
	{
		mClient.newGame(10, 6);
		mPlayerName = mClient.getPlayerName();
		mClient.getStatus(mpGettingStatusHandler);
		mPlayerView1.postDelayed(mpIterator, 100);
		mIsFinish = false;
	}

	//=========================================================================
	private void updateView () {
		Map<Integer, Integer> freeLoaves = mLoavesStatus.getFreeLoaves();
		GuiLoaf [] loaves = new GuiLoaf[freeLoaves.size()];
		int lCount = 0;
		Set<Map.Entry<Integer, Integer>> set = freeLoaves.entrySet();

		for(Map.Entry<Integer, Integer> entry : set)
		{
			loaves[lCount] = new GuiLoaf(entry.getKey().intValue(), entry.getValue().intValue());
			lCount++;
		}
		mLoavesList.setLoaves(loaves);
		
		Set<Map.Entry<String, EatingLoaf>> players = mLoavesStatus.getEaters().entrySet();

		boolean isFirst = true;
		for(Map.Entry<String, EatingLoaf> entry : players) {
			Person t = isFirst ? mPlayerView1 : mPlayerView2;

			t.setName(entry.getKey());
			if(entry.getValue() != null)
			{
				t.setLoaf(entry.getValue().getTail(), entry.getValue().getWeight());
			}
			else
			{
				t.setLoaf(-1, -1);
			}
			if(!isFirst)
			{
				break;
			}

			isFirst = !isFirst;
		}
	}
	
	private boolean isFinish ()
	{
		if(!mLoavesStatus.getFreeLoaves().isEmpty())
			return false;

		Set<Map.Entry<String, EatingLoaf>> set = mLoavesStatus.getEaters().entrySet();

		for(Map.Entry<String, EatingLoaf> entry : set)
		{
			if(entry.getValue() != null)
			{
				return false;
			}
		}
		
		return true;
	}

	private Runnable mpIterator = new Runnable() {

		public void run() {
			if(mIsFinish)
				return;
			mClient.getStatus(mpGettingStatusHandler);
			mPlayerView1.postDelayed(this, 100);
		}
	};
	

	private IGettingsStatusHandler mpGettingStatusHandler = new IGettingsStatusHandler() {
		public void handle(LoavesStatus status) {

			mLoavesStatus = status;

			if(isFinish())
			{
				StringBuilder sb = new StringBuilder();
				AlertDialog.Builder b = new AlertDialog.Builder(mActivity);
				Set<Map.Entry<String, Integer>> set = mLoavesStatus.getResults().entrySet();

				for(Map.Entry<String, Integer> entry : set)
				{
					sb.append(entry.getKey());
					sb.append(": ");
					sb.append(Integer.toString(entry.getValue().intValue() / 1000));
					sb.append("\n");
				}
				
				b.setMessage(sb.toString());
				b.create().show();
				mIsFinish = true;
			}
			else
			{
				updateView();
			}
		}
	};

	private class LoafClickListener implements OnItemClickListener {
		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			int loafNumber = mLoavesList.getLoaf(arg2).name;

			mClient.tryToEatLoaf(mPlayerName, loafNumber);
		}
	};
}
